Auto merge of #5213 - Eh2406:faster_resolver, r=alexcrichton
authorbors <bors@rust-lang.org>
Sat, 24 Mar 2018 16:59:59 +0000 (16:59 +0000)
committerbors <bors@rust-lang.org>
Sat, 24 Mar 2018 16:59:59 +0000 (16:59 +0000)
commit93b0b1253e7ce1f9fa585297f51aea1c68f554eb
tree154a34aa2dd17da83c178704b94fa1ebacaedb0b
parentbcd0300f0e2b572e81fa17e88dcb927aa95d6b4e
parenta7a1341cf5f32bf6b5af12af672876a5c9b392bb
Auto merge of #5213 - Eh2406:faster_resolver, r=alexcrichton

Faster resolver: use a inverse-index to not activate the causes of conflict

This adds a test for https://github.com/rust-lang/cargo/issues/4810#issuecomment-357553286 with two extensions that make it harder. It is the last reproducible and in the wild exponentially slow resolution (that I have found).

The problem in the test is `backtrack_trap0 = "*"` is a lot of ways of saying `constrained = ">=1.1.0, <=2.0.0"` but `constrained= "2.0.1"` is already picked. Only then to try and solve `constrained= "~1.0.0"` which is incompatible. Our parent knows that we have been poisoned, and wont try to activate us again.  Because of the order we evaluate deps we end up backtracking to where `constrained: 1.1.0` is set instead of our parent. And so the poisoning does not help. This is harder then https://github.com/rust-lang/cargo/issues/4810#issuecomment-357553286 because:

1. Having multiple semver compatible versions of constrained in play makes for a lot more bookkeeping. Specifically bookkeeping I forgot when I first submitted this PR.
2. The problematic dependencies are added deep in a combinatorial explosion of possibilities. So if we don't correctly handle caching that `backtrack_trap0 = "*"` is doomed then we will never finish looking thru the different possibilities for `level0 = "*"`

This PR also includes a proof of concept solution for the test, which proves that it does solve https://github.com/rust-lang/cargo/issues/4810#issuecomment-357553286. The added code is tricky to read. It also adds a `O(remaining_deps)` job to every activation on the happy path, slower if the `past_conflicting_activations` is not empty.

I'd like some brainstorming on better solutions.